/*
 *	This file is part of Lounge-Cast.
 *
 *  Author:  	Markus Moormann
 *	E-mail:  	mmoorman@uni-osnabrueck.de
 *	Copyright:	University of Osnabrueck (Zentrum Virtuos)
 * 	Website:	www.uni-osnabrueck.de
 *	Date:		16.02.2011
 *
 *	Lounge-Cast is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *	Lounge-Cast is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Lounge-Cast.  If not, see <http://www.gnu.org/licenses/>.
 */
package multimedia.control.command
{
	import com.adobe.cairngorm.commands.ICommand;
	import com.adobe.cairngorm.commands.SequenceCommand;
	import com.adobe.cairngorm.control.CairngormEvent;
	
	import flash.events.TimerEvent;
	import flash.system.Capabilities;
	import flash.text.TextFormatAlign;
	import flash.utils.Dictionary;
	import flash.utils.Timer;
	
	import multimedia.control.event.LoadTextEvent;
	import multimedia.model.ModelLocator;
	import multimedia.model.vo.MediaElementVO;
	import multimedia.model.vo.TextVO;
	import multimedia.util.LogUtil;
	
	import mx.logging.ILogger;
	import mx.rpc.CallResponder;
	
	import org.osmf.elements.DurationElement;
	import org.osmf.elements.ImageElement;
	import org.osmf.elements.ParallelElement;
	import org.osmf.elements.TextElement;
	import org.osmf.elements.VideoElement;
	import org.osmf.events.LoadEvent;
	import org.osmf.events.MetadataEvent;
	import org.osmf.layout.LayoutMetadata;
	import org.osmf.layout.LayoutMode;
	import org.osmf.media.MediaElement;
	import org.osmf.media.MediaType;
	import org.osmf.media.URLResource;
	import org.osmf.traits.DisplayObjectTrait;
	import org.osmf.traits.LoadState;
	import org.osmf.traits.LoadTrait;
	import org.osmf.traits.MediaTraitType;

	public class LoadTextCommand extends SequenceCommand implements ICommand
	{
		
		private static const LOG:ILogger = LogUtil.getLogger(LoadTextCommand);
		private var e:LoadTextEvent;

		private var media:ParallelElement;

		private var model:ModelLocator = ModelLocator.getInstance();
		
		private var text:MediaElement;

		private var image:MediaElement;
		private var video:VideoElement;
		private var background_image:MediaElement;
		private var image_source:MediaElement;
		
		private var imageView:ParallelElement;
		private var videoView:ParallelElement;

		private var imageLayout:LayoutMetadata;
		private var backgroundImageLayout:LayoutMetadata;
		private var sourceLayout:LayoutMetadata;
		private var textLayout:LayoutMetadata;
		private var parallelLayout:LayoutMetadata;
		
		private var sizes:Dictionary = new Dictionary();
		
		private var height:Number;
		private var width:Number;
		private var textHeight:Number;
		private var textWidth:Number;
		private var subHeight:Number;
		private var subWidth:Number;
		
		private var fitHeightTimer:Timer;
		private var lastEvent:LoadEvent;
		
		private var publish_date:MediaElement;
		private var publish_layout:LayoutMetadata;


		override public function execute(event:CairngormEvent):void
		{
			LOG.debug("<<< Executing LoadTextCommand ({0}) >>>", (event as LoadTextEvent).text.mediaId);
			model.log += "\nLoadTextCommand";
			this.e = event as LoadTextEvent;
			this.nextEvent = e.nextEvent;
			
			height = Capabilities.screenResolutionY
			width = Capabilities.screenResolutionX;
			
			initSizes();

			media = new ParallelElement();

			this.model = ModelLocator.getInstance();
			
			if(e.text.publish_date != "")
			{
				publish_date = new DurationElement(e.text.duration,
								new TextElement(e.text.publish_date, true, TextFormatAlign.RIGHT, 100, 130));
				publish_layout = new LayoutMetadata();
				publish_date.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, publish_layout);
				publish_layout.bottom = e.text.margin_bottom;
				publish_layout.right = e.text.margin_right;
				publish_layout.index = 2;
			}
			
			var title:String = '<TEXTFORMAT><FONT COLOR="#' + e.text.title_color.toString(16) + '">' +
								"<p><b>" + e.text.title + "</b></p>\n" +
							   '</FONT></TEXTFORMAT>'
			title = e.text.hide_title ? "" : title;
			
			if(e.text.image == "" && e.text.video == "")
			{
				text = new DurationElement(e.text.duration,
						new TextElement(title + e.text.formatedText, 
						 			    true, 
										TextFormatAlign.LEFT, 
										height - e.text.margin_bottom - e.text.margin_top - 10, 
										width - e.text.margin_left - e.text.margin_right));
				textLayout = new LayoutMetadata();
				text.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, textLayout);
				textLayout.top = e.text.margin_top;
				textLayout.bottom = e.text.margin_bottom;
				textLayout.left = e.text.margin_left;
				textLayout.right = e.text.margin_right;
				textLayout.index = 2;
				if(e.text.background_image != null && e.text.background_image != "")
				{
					background_image = new ImageElement(new URLResource(e.text.background_image));
					var parallel:ParallelElement = new ParallelElement();
					parallel.addChild(text);
					parallel.addChild(background_image);
					
					if(publish_date != null)
					{
						parallel.addChild(publish_date);
					}
					
					backgroundImageLayout = new LayoutMetadata();
					background_image.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, backgroundImageLayout);
					backgroundImageLayout.width = width;
					backgroundImageLayout.height = height;
					(background_image.getTrait(MediaTraitType.LOAD) as LoadTrait).load();
					model.mediaElements[(model.counter + 1)%4] = new MediaElementVO(e.text, parallel);
				}else if (publish_date != null) 
				{
					parallel = new ParallelElement();
					parallel.addChild(text);
					parallel.addChild(publish_date);
					model.mediaElements[(model.counter + 1)%4] = new MediaElementVO(e.text, parallel)
				} else {
					model.mediaElements[(model.counter + 1)%4] = new MediaElementVO(e.text, text)
				}
			} else if (e.text.image != "")
			{
				textHeight = height - e.text.margin_bottom - e.text.margin_top;
				subHeight = ((e.text.image_orientation == TextVO.BOTTOM || e.text.image_orientation == TextVO.TOP) ? sizes["image-width-" + e.text.image_orientation] / e.text.image_aspect_ratio : 0);
				textWidth = width - e.text.margin_left - e.text.margin_right;
				subWidth = ((e.text.image_orientation == TextVO.LEFT || e.text.image_orientation == TextVO.RIGHT) ? sizes["image-width-" + e.text.image_orientation] : 0); 
				text = new DurationElement(e.text.duration,
							new TextElement(title + e.text.formatedText, 
											true, 
											TextFormatAlign.LEFT, 
											textHeight - subHeight, 
											textWidth - subWidth));
				
				var imageResource:URLResource = new URLResource(e.text.image);
				imageResource.mediaType = MediaType.IMAGE;
				image = new DurationElement(e.text.duration, 
							new ImageElement(imageResource));
				image_source = new DurationElement(e.text.duration,
									new TextElement(e.text.image_source, false));
				

				
				//create a parallelView for the image side of the TextView, so that 
				//the image_source is always shown directly below the image
				imageView = new ParallelElement();
				
				//set some layout values
				imageLayout = new LayoutMetadata();
				image.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, imageLayout);
				imageLayout.width = sizes["image-width-" + e.text.image_orientation];
				imageLayout.height = imageLayout.width / e.text.image_aspect_ratio;
				imageLayout.index = 1;
				
				var imageSourceLayout:LayoutMetadata = new LayoutMetadata();
				image_source.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, imageSourceLayout);
				imageSourceLayout.percentWidth = 100;
				imageSourceLayout.percentHeight = 100;
				imageSourceLayout.index = 2;
				
				imageView.addChild(image);
				imageView.addChild(image_source);
				
				var imageViewLayout:LayoutMetadata = new LayoutMetadata();
				imageView.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, imageViewLayout);
				imageViewLayout.percentWidth = sizes["imageView-percentWidth-" + e.text.image_orientation];
				imageViewLayout.percentHeight = sizes["imageView-percentHeight-" + e.text.image_orientation];
				imageViewLayout.index = (e.text.image_orientation == TextVO.LEFT ? 1 : 2);
				imageViewLayout.layoutMode = LayoutMode.VERTICAL;
				media.addChild(imageView);
				
				textLayout = new LayoutMetadata();
				text.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, textLayout);
				textLayout.index = (e.text.image_orientation == TextVO.LEFT ? 2 : 1);;
				media.addChild(text);
				
				if(publish_date != null)
				{
					media.addChild(publish_date);
				}
				
				parallelLayout = new LayoutMetadata();
				media.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, parallelLayout);
				parallelLayout.height = height;
				parallelLayout.width = width;
				parallelLayout.bottom = e.text.margin_bottom;
				parallelLayout.left = e.text.margin_left;
				parallelLayout.top = e.text.margin_top;
				parallelLayout.right = e.text.margin_right;
				parallelLayout.index = 2;
				parallelLayout.layoutMode = ((e.text.image_orientation == TextVO.LEFT || e.text.image_orientation == TextVO.RIGHT) ? LayoutMode.HORIZONTAL : LayoutMode.VERTICAL);
				
				if(e.text.background_image != null && e.text.background_image != "")
				{
					background_image = new ImageElement(new URLResource(e.text.background_image));
					backgroundImageLayout = new LayoutMetadata();
					background_image.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, backgroundImageLayout);
					backgroundImageLayout.width = width;
					backgroundImageLayout.height = height;
					backgroundImageLayout.index = 1;
					var par:ParallelElement = new ParallelElement();
					var parLayout:LayoutMetadata = new LayoutMetadata();
					par.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, parLayout);
					parLayout.layoutMode = LayoutMode.NONE;
					
					par.addChild(background_image);
					par.addChild(media);
					(par.getTrait(MediaTraitType.LOAD) as LoadTrait).load();
					model.mediaElements[(model.counter + 1)%4] = new MediaElementVO(e.text, par)
				} else
				{
					(media.getTrait(MediaTraitType.LOAD) as LoadTrait).load();
					model.mediaElements[(model.counter + 1)%4] = new MediaElementVO(e.text, media)
				}
	
			} else if(e.text.video != "")
			{
				textHeight = height - e.text.margin_bottom - e.text.margin_top;
				subHeight = ((e.text.image_orientation == TextVO.BOTTOM || e.text.image_orientation == TextVO.TOP) ? sizes["image-width-" + e.text.image_orientation] / e.text.image_aspect_ratio : 0);
				textWidth = width - e.text.margin_left - e.text.margin_right;
				subWidth = ((e.text.image_orientation == TextVO.LEFT || e.text.image_orientation == TextVO.RIGHT) ? sizes["image-width-" + e.text.image_orientation] : 0); 
				text = new DurationElement(e.text.duration,
					new TextElement(title + e.text.formatedText, 
									true, 
									TextFormatAlign.LEFT, 
									textHeight - subHeight, 
									textWidth - subWidth));
				
				var videoResource:URLResource = new URLResource(e.text.video);
				video = new VideoElement(videoResource);
				image_source = new TextElement(e.text.image_source, false)
				
				//create a parallelView for the image side of the TextView, so that 
				//the image_source is always shown directly below the image
				videoView = new ParallelElement();
				
				//set some layout values
				var videoLayout:LayoutMetadata = new LayoutMetadata();
				videoLayout.index = 0;
				video.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, videoLayout);
				videoLayout.width = sizes["image-width-" + e.text.image_orientation];
				videoLayout.height = videoLayout.width / (e.text.video_aspect_ratio == "16:9" ? (16/9) : (4/3));
				
				var videoSourceLayout:LayoutMetadata = new LayoutMetadata();
				videoSourceLayout.index =1;
				image_source.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, videoSourceLayout);
				
				videoView.addChild(video);
				videoView.addChild(image_source);
				
				var videoViewLayout:LayoutMetadata = new LayoutMetadata();
				video.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, videoViewLayout);
				videoViewLayout.percentWidth = sizes["imageView-percentWidth-" + e.text.image_orientation];
				videoViewLayout.percentHeight = sizes["imageView-percentHeight-" + e.text.image_orientation];
				videoViewLayout.index = (e.text.image_orientation == TextVO.LEFT ? 1 : 2);
				videoViewLayout.layoutMode = LayoutMode.VERTICAL;
				media.addChild(video);
				
				
				textLayout = new LayoutMetadata();
				text.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, textLayout);
				textLayout.index = (e.text.image_orientation == TextVO.LEFT ? 2 : 1);;
				media.addChild(text);
				
				parallelLayout = new LayoutMetadata();
				media.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, parallelLayout);
				parallelLayout.height = height;
				parallelLayout.width = width;
				parallelLayout.bottom = e.text.margin_bottom;
				parallelLayout.left = e.text.margin_left;
				parallelLayout.top = e.text.margin_top;
				parallelLayout.right = e.text.margin_right;
				parallelLayout.layoutMode = ((e.text.image_orientation == TextVO.LEFT || e.text.image_orientation == TextVO.RIGHT) ? LayoutMode.HORIZONTAL : LayoutMode.VERTICAL);
					
				(media.getTrait(MediaTraitType.LOAD) as LoadTrait).load();
				
				model.mediaElements[(model.counter + 1)%4] = new MediaElementVO(e.text, media) 
			}
			
			executeNextCommand();
		}

		private function fitHeight(event:LoadEvent):void
		{
			if (event.loadState == LoadState.READY)
			{
				var test:Object = image.getTrait(MediaTraitType.DISPLAY_OBJECT);
				var view:DisplayObjectTrait = image.getTrait(MediaTraitType.DISPLAY_OBJECT) as DisplayObjectTrait;
				imageLayout.height = (imageLayout.width / e.text.image_width) * e.text.image_height;
			}
		}
		
		private function onTimer(event:TimerEvent):void
		{
			fitHeightTimer.stop();
			fitHeight(lastEvent);
		}
		
		private function initSizes():void
		{
			sizes["image-width-left"] = width * 0.3;
			sizes["image-width-right"] = width * 0.3;
			sizes["image-width-top"] = width * 0.9;
			sizes["image-width-bottom"] = width* 0.9;
			
			sizes["imageView-percentWidth-left"] = 30;
			sizes["imageView-percentWidth-right"] = 30;
			sizes["imageView-percentWidth-top"] = 100;
			sizes["imageView-percentWidth-bottom"] = 100;
			
			sizes["imageView-percentHeight-left"] = 100;
			sizes["imageView-percentHeight-right"] = 100;
			sizes["imageView-percentHeight-top"] = 30;
			sizes["imageView-percentHeight-bottom"] = 30;
			
			sizes["imageView-percentX-left"] = 0;
			sizes["imageView-percentX-right"] = 64;
			sizes["imageView-percentX-top"] = 0;
			sizes["imageView-percentX-bottom"] = 0;
			
			sizes["imageView-percentY-left"] = 0;
			sizes["imageView-percentY-right"] = 0;
			sizes["imageView-percentY-top"] = 0;
			sizes["imageView-percentY-bottom"] = 68;
			
			sizes["imageView-layoutMode-left"] = LayoutMode.VERTICAL;
			sizes["imageView-layoutMode-right"] = LayoutMode.VERTICAL;
			sizes["imageView-layoutMode-top"] = LayoutMode.HORIZONTAL;
			sizes["imageView-layoutMode-bottom"] = LayoutMode.HORIZONTAL;
			
			sizes["text-percentWidth-left"] = 70;
			sizes["text-percentWidth-right"] = 70;
			sizes["text-percentWidth-top"] = 100;
			sizes["text-percentWidth-bottom"] = 100;
			
			sizes["text-percentHeight-left"] = 90;
			sizes["text-percentHeigh-right"] = 90;
			sizes["text-percentHeigh-top"] = 72;
			sizes["text-percentHeigh-bottom"] = 72;
			
			sizes["text-percentX-left"] = 32;
			sizes["text-percentX-right"] = 0;
			sizes["text-percentX-top"] = 0;
			sizes["text-percentX-bottom"] = 0;
			
			sizes["text-percentY-left"] = 0;
			sizes["text-percentY-right"] = 0;
			sizes["text-percentY-top"] = 28;
			sizes["text-percentY-bottom"] = 0;
			
			sizes["text-width-factor-left"] = 0.60;
			sizes["text-width-factor-right"] = 0.60;
			sizes["text-width-factor-top"] = 1;
			sizes["text-width-factor-bottom"] = 1;
			
			sizes["text-height-factor-left"] = 0.80;
			sizes["text-height-factor-right"] = 0.80;
			sizes["text-height-factor-top"] = 0.68;
			sizes["text-height-factor-bottom"] = 0.68;
			
		}

	}
}